package com.joolun.web.controller.mall;

import com.google.common.collect.Lists;
import com.joolun.common.annotation.Log;
import com.joolun.common.core.controller.BaseController;
import com.joolun.common.core.domain.AjaxResult;
import com.joolun.common.core.page.TableDataInfo;
import com.joolun.common.enums.BusinessType;
import com.joolun.common.utils.poi.ExcelUtil;
import com.joolun.system.domain.Area;
import com.joolun.system.domain.vo.AreaInitVO;
import com.joolun.system.service.IAreaService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 行政区域Controller
 *
 * @author www.tryerlee.com
 * @date 2021-12-23
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/logistics/area")
@Api(value = "area", tags = "行政区域API")
public class AreaController extends BaseController {
    @Autowired
    private IAreaService areaService;

    @ApiOperation(value = "返回所有行政区域")
    @GetMapping("/all")
    public AjaxResult all() {
        List<Area> list = areaService.list();
        List<Area> provinceList = list.stream().filter(m -> m.getCode().endsWith("0000")).collect(Collectors.toList());
        List<String> provinceCodeList = provinceList.stream().map(Area::getCode).collect(Collectors.toList());

        List<Area> cityList = list.stream().filter(m -> m.getCode().endsWith("00") && provinceCodeList.contains(m.getParentCode())).collect(Collectors.toList());
        Map<String, List<Area>> cityMap = cityList.stream().collect(Collectors.groupingBy(Area::getParentCode));

        List<Area> areaList = list.stream().filter(m -> !m.getCode().endsWith("00")).collect(Collectors.toList());
        Map<String, List<Area>> areaMap = areaList.stream().collect(Collectors.groupingBy(Area::getParentCode));

        provinceList.forEach(m -> {
            List<Area> cities = cityMap.get(m.getCode());
            cities.forEach(n -> {
                List<Area> areas = areaMap.get(n.getCode());
                n.setChilds(areas);
            });
            m.setChilds(cities);
        });
        return AjaxResult.success(provinceList);
    }

    @ApiOperation(value = "返回初始化行政区域下拉框")
    @GetMapping("/init/{code}")
    public AjaxResult init(@PathVariable("code") String code) {
        String rootCode = "0";
        if (Objects.isNull(code) || code.equals(rootCode)) {
            return init();
        } else if (code.length() != 6) {
            return AjaxResult.error("参数错误, code必须为6位行政区域编码");
        }
        AreaInitVO vo;
        //省
        if (code.endsWith("0000")) {
            String provinceCode = code.substring(0, 2) + "0000";
            List<Area> provinceList = areaService.selectAreaListByParentCode(rootCode);
            List<Area> cityList = areaService.selectAreaListByParentCode(provinceCode);
            List<Area> areaList = Lists.newArrayList();
            Optional<Area> cityOptional = cityList.stream().findFirst();
            if (cityOptional.isPresent()) {
                String cityCode = cityOptional.get().getCode();
                areaList = areaService.selectAreaListByParentCode(cityCode);
            }
            vo = new AreaInitVO(provinceList, cityList, areaList);
        } else {
            //区 || 市
            String provinceCode = code.substring(0, 2) + "0000";
            String cityCode = code.substring(0, 4) + "00";
            List<Area> provinceList = areaService.selectAreaListByParentCode(rootCode);
            List<Area> cityList = areaService.selectAreaListByParentCode(provinceCode);
            List<Area> areaList = areaService.selectAreaListByParentCode(cityCode);
            vo = new AreaInitVO(provinceList, cityList, areaList);
        }
        return AjaxResult.success(vo);
    }

    @ApiOperation(value = "返回初始化行政区域下拉框")
    @GetMapping("/init")
    public AjaxResult init() {
        List<Area> provinceList = areaService.selectAreaListByParentCode("0");
        List<Area> cityList = Lists.newArrayList();
        List<Area> areaList = Lists.newArrayList();
        Optional<Area> cityOptional = provinceList.stream().findFirst();
        if (cityOptional.isPresent()) {
            String cityCode = cityOptional.get().getCode();
            cityList = areaService.selectAreaListByParentCode(cityCode);

            Optional<Area> areaOptional = cityList.stream().findFirst();
            if (areaOptional.isPresent()) {
                String areaCode = areaOptional.get().getCode();
                areaList = areaService.selectAreaListByParentCode(areaCode);
            }
        }
        AreaInitVO vo = new AreaInitVO(provinceList, cityList, areaList);
        return AjaxResult.success(vo);
    }

    @ApiOperation(value = "根据父级编码获取子级区域列表")
    @GetMapping("/getListByParentCode")
    public AjaxResult getListByParentCode(@RequestParam("parentCode") String parentCode) {
        List<Area> list = areaService.selectAreaListByParentCode(parentCode);
        return AjaxResult.success(list);
    }

    /**
     * 查询行政区域列表
     */
    @PreAuthorize("@ss.hasPermi('system:area:list')")
    @GetMapping("/list")
    public TableDataInfo list(Area area) {
        startPage();
        List<Area> list = areaService.selectAreaList(area);
        return getDataTable(list);
    }

    /**
     * 导出行政区域列表
     */
    @PreAuthorize("@ss.hasPermi('system:area:export')")
    @Log(title = "行政区域", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(Area area) {
        List<Area> list = areaService.selectAreaList(area);
        ExcelUtil<Area> util = new ExcelUtil<Area>(Area.class);
        return util.exportExcel(list, "area");
    }

    /**
     * 获取行政区域详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:area:query')")
    @GetMapping(value = "/{code}")
    public AjaxResult getInfo(@PathVariable("code") String code) {
        return AjaxResult.success(areaService.selectAreaById(code));
    }

    /**
     * 新增行政区域
     */
    @PreAuthorize("@ss.hasPermi('system:area:add')")
    @Log(title = "行政区域", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Area area) {
        return toAjax(areaService.insertArea(area));
    }

    /**
     * 修改行政区域
     */
    @PreAuthorize("@ss.hasPermi('system:area:edit')")
    @Log(title = "行政区域", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Area area) {
        return toAjax(areaService.updateArea(area));
    }

    /**
     * 删除行政区域
     */
    @PreAuthorize("@ss.hasPermi('system:area:remove')")
    @Log(title = "行政区域", businessType = BusinessType.DELETE)
    @DeleteMapping("/{codes}")
    public AjaxResult remove(@PathVariable String[] codes) {
        return toAjax(areaService.deleteAreaByIds(codes));
    }
}
